#include <vector>
#include <array>
using namespace std;
class trie_node
{
public:
    friend class trie_tree;
    trie_node(bool is_one = false) : val(is_one), num(0)
    {
        sons.fill(nullptr);
    }

private:
    bool val;
    array<trie_node *, 2> sons;
    // for the last node
    int num;
};
class trie_tree
{
public:
    void insert(const int num)
    {
        trie_node *cur = root;
        for (int i = 31; i >= 0; i--)
        {
            bool is_one = num & (1 << i);
            if (!cur->sons[is_one])
                cur->sons[is_one] = new trie_node(is_one);
            cur = cur->sons[is_one];
        }
        cur->num = num;
    }
    int get_max_XOR(const int num)
    {
        trie_node *cur = root;
        for (int i = 31; i >= 0; i--)
        {
            bool is_one = num & (1 << i);
            cur = cur->sons[!is_one] ? cur->sons[!is_one] : cur->sons[is_one];
        }
        return num ^ cur->num;
    }

private:
    trie_node *root = new trie_node;
};
class Solution
{
public:
    int findMaximumXOR(vector<int> &nums)
    {
        if (!nums.size())
            return 0;
        int res = 0;
        trie_tree trie;
        trie.insert(nums[0]);
        for (int i = 1; i < nums.size(); i++)
        {
            res = max(trie.get_max_XOR(nums[i]), res);
            trie.insert(nums[i]);
        }
        return res;
    }
};